/*
 * @Author: LiuYan 15136056318@163.com
 * @Date: 2023-12-01 13:48:22
 * @LastEditors: LiuYan 15136056318@163.com
 * @LastEditTime: 2023-12-06 10:43:52
 * @FilePath: \react-template_pc\src\components\infinite-roll\index.tsx
 * @Description: 无限滚动
 */
import React from 'react' // 导入React中的useEffect和useRef函数
import type { InfiniteRollProps } from './data' // 导入InfiniteRollProps类型定义
import { useReactive } from '@/hooks' // 导入useReactive自定义hook
interface AnimationArgs {
  rootEl: HTMLElement // 定义AnimationArgs接口，包含rootEl属性，类型为HTMLElement
  maxHeight: number // 定义maxHeight属性，类型为number
  scllorTop: number
}
const InfiniteRoll = ({ children, duration = 0.2 }: InfiniteRollProps) => {
  const domRef = React.useRef<any>(null) // 创建domRef引用，初始值为null
  const { state } = useReactive({
    showLastChild: false, // 使用useReactive自定义hook，初始化state对象，包含showLastChild属性，初始值为false
  })
  let animation: null | (({ rootEl, maxHeight, scllorTop }: AnimationArgs) => void) = ({
    rootEl,
    maxHeight,
    scllorTop,
  }: AnimationArgs) => {
    if (maxHeight > 0 && scllorTop >= maxHeight) {
      scllorTop = 0
    }
    scllorTop += duration
    rootEl.style.transform = `translateY(-${scllorTop}px)` // 设置rootEl元素的transform样式属性为translateY(-value}px)
    if (animation) {
      window.requestAnimationFrame(animation.bind(null, { rootEl, maxHeight, scllorTop })) // 使用window.requestAnimationFrame函数进行动画帧请求，绑定动画函数并传入参数
    }
  }
  React.useEffect(() => {
    const scllorTop: number = 0
    const rootEl: HTMLElement = domRef.current as HTMLElement // 将domRef引用赋值给rootEl变量
    const maxHeight = rootEl.clientHeight / 2 // 计算maxHeight值为rootEl元素的clientHeight属性的一半
    const parentNode = rootEl.parentNode as HTMLElement // 将rootEl的父节点赋值给parentNode变量
    if (
      maxHeight && state.showLastChild
        ? parentNode.clientHeight < maxHeight // 如果maxHeight大于0且state.showLastChild为true且parentNode的clientHeight小于maxHeight
        : parentNode.clientHeight < rootEl.clientHeight // 否则如果parentNode的clientHeight小于rootEl的clientHeight
    ) {
      if (animation) {
        animation({
          rootEl,
          maxHeight,
          scllorTop,
        }) // 调用animation函数，传入参数
      }
      state.showLastChild = true // 设置state.showLastChild为true
    } else {
      state.showLastChild = false // 设置state.showLastChild为false
    }
    return () => {
      if (animation) animation = null // 清空animation变量
    }
  }, [children])
  return (
    <div ref={domRef}>
      {/* 渲染children */}
      <div>{children}</div>
      {/* 根据state.showLastChild的值决定是否渲染children */}
      <div style={{ display: state.showLastChild ? 'block' : 'none' }}>{children}</div>
    </div>
  )
}
export default InfiniteRoll // 导出InfiniteRoll组件
